/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;

namespace DaveSexton.DocProject
{
	internal sealed class RemoteDelegateProxy : MarshalByRefObject
	{
		#region Public Properties
		public Delegate Substitute
		{
			get
			{
				return substitute;
			}
		}
		#endregion

		#region Private / Protected
		private readonly Delegate target, substitute;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="RemoteDelegateProxy" /> class.
		/// </summary>
		public RemoteDelegateProxy(Delegate target)
		{
			if (target == null)
				throw new ArgumentNullException("target");

			this.target = target;

			if (target is EventHandler)
				substitute = (EventHandler) _EventHandler;
			else if (target is Callback)
				substitute = (Callback) V0;
			else if (target is System.Windows.Forms.MethodInvoker)
				substitute = (System.Windows.Forms.MethodInvoker) V0;
			else if (target is BuildStepExecuteCallback)
				substitute = (BuildStepExecuteCallback) _BuildStepExecuteCallback;
			else
			{
				string invokerName = (target.Method.ReturnType == typeof(void)) ? "V" : "R";
				invokerName += target.Method.GetParameters().Length;

				string thisName = this.GetType().FullName;
				Type type = Type.GetType(thisName + "+_" + invokerName);

				this.substitute = Delegate.CreateDelegate(type, this, invokerName);
			}
		}
		#endregion

		#region Methods
		public override object InitializeLifetimeService()
		{
			return null;
		}

		public void _EventHandler(object sender, EventArgs e)
		{
			target.DynamicInvoke(sender, e);
		}

		public void _BuildStepExecuteCallback(BuildContext context)
		{
			target.DynamicInvoke(context);
		}

		private delegate object _R0();
		public object R0()
		{
			return target.DynamicInvoke();
		}

		private delegate object _R1(object a1);
		public object R1(object a1)
		{
			return target.DynamicInvoke(a1);
		}

		private delegate object _R2(object a1, object a2);
		public object R2(object a1, object a2)
		{
			return target.DynamicInvoke(a1, a2);
		}

		private delegate object _R3(object a1, object a2, object a3);
		public object R3(object a1, object a2, object a3)
		{
			return target.DynamicInvoke(a1, a2, a3);
		}

		private delegate object _R4(object a1, object a2, object a3, object a4);
		public object R4(object a1, object a2, object a3, object a4)
		{
			return target.DynamicInvoke(a1, a2, a3, a4);
		}

		private delegate object _R5(object a1, object a2, object a3, object a4, object a5);
		public object R5(object a1, object a2, object a3, object a4, object a5)
		{
			return target.DynamicInvoke(a1, a2, a3, a4, a5);
		}

		private delegate object _R6(object a1, object a2, object a3, object a4, object a5, object a6);
		public object R6(object a1, object a2, object a3, object a4, object a5, object a6)
		{
			return target.DynamicInvoke(a1, a2, a3, a4, a5, a6);
		}

		private delegate object _R7(object a1, object a2, object a3, object a4, object a5, object a6, object a7);
		public object R7(object a1, object a2, object a3, object a4, object a5, object a6, object a7)
		{
			return target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7);
		}

		private delegate object _R8(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8);
		public object R8(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8)
		{
			return target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7, a8);
		}

		private delegate object _R9(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9);
		public object R9(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9)
		{
			return target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7, a8, a9);
		}

		private delegate object _R10(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9, object a10);
		public object R10(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9, object a10)
		{
			return target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
		}

		private delegate void _V0();
		public void V0()
		{
			target.DynamicInvoke();
		}

		private delegate void _V1(object a1);
		public void V1(object a1)
		{
			target.DynamicInvoke(a1);
		}

		private delegate void _V2(object a1, object a2);
		public void V2(object a1, object a2)
		{
			target.DynamicInvoke(a1, a2);
		}

		private delegate void _V3(object a1, object a2, object a3);
		public void V3(object a1, object a2, object a3)
		{
			target.DynamicInvoke(a1, a2, a3);
		}

		private delegate void _V4(object a1, object a2, object a3, object a4);
		public void V4(object a1, object a2, object a3, object a4)
		{
			target.DynamicInvoke(a1, a2, a3, a4);
		}

		private delegate void _V5(object a1, object a2, object a3, object a4, object a5);
		public void V5(object a1, object a2, object a3, object a4, object a5)
		{
			target.DynamicInvoke(a1, a2, a3, a4, a5);
		}

		private delegate void _V6(object a1, object a2, object a3, object a4, object a5, object a6);
		public void V6(object a1, object a2, object a3, object a4, object a5, object a6)
		{
			target.DynamicInvoke(a1, a2, a3, a4, a5, a6);
		}

		private delegate void _V7(object a1, object a2, object a3, object a4, object a5, object a6, object a7);
		public void V7(object a1, object a2, object a3, object a4, object a5, object a6, object a7)
		{
			target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7);
		}

		private delegate void _V8(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8);
		public void V8(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8)
		{
			target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7, a8);
		}

		private delegate void _V9(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9);
		public void V9(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9)
		{
			target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7, a8, a9);
		}

		private delegate void _V10(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9, object a10);
		public void V10(object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8, object a9, object a10)
		{
			target.DynamicInvoke(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
		}
		#endregion
	}
}
